package org.skyui.views;

import java.text.Format;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.skyui.beans.AbstractBean;
import org.skyui.beans.AbstractBean.SelectableValue;

import com.vaadin.data.*;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItem;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DateField;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.AbstractSelect.Filtering;
import com.vaadin.ui.TextField;

public class FieldFactoryImpl extends DefaultFieldFactory {

    @Override
    public Field createField(Item item, Object propertyId, Component uiContext) {

	Field field;
	AbstractBean bean = ((BeanItem<? extends AbstractBean>) item).getBean();

	SelectableValue[] options;
	Map<String, SelectableValue[]> selectables = bean.getSelectablesMap();
	if (selectables != null
		&& (options = selectables.get(propertyId)) != null) {
	    String fieldType = bean.getSelectableLooksMap().get(propertyId);
	    List optionStrings = new ArrayList();
	    for (SelectableValue sv : options) {
		optionStrings.add(sv.value);
	    }

	    if (fieldType.equals("OptionGroup"))
		field = new OptionGroup((String) propertyId, optionStrings);
	    else {
		ComboBox c = new ComboBox((String) propertyId, optionStrings);
		c.setFilteringMode(Filtering.FILTERINGMODE_CONTAINS);
		c.setImmediate(true);
		c.setNullSelectionAllowed(false);
		if (optionStrings.size() == 1) {
		    c.setValue(optionStrings.get(0));
		}
		field = c;
	    }

	} else {

	    Class<?> type = item.getItemProperty(propertyId).getType();
	    field = createFieldByPropertyType(type);
	    if (field instanceof DateField) {
		field = new LiveDateField();
		((DateField) field).setResolution(DateField.RESOLUTION_MIN);
	    }
	    field.setCaption(createCaptionByPropertyId(propertyId));
	}

	Set<String> dontShowSet = bean.getDontShowSet();
	if (dontShowSet != null && dontShowSet.contains(propertyId))
	    return null;

	Set<String> isRequiredSet = bean.getIsRequiredSet();
	if (isRequiredSet != null && isRequiredSet.contains(propertyId))
	    field.setRequired(true);

	Set<String> isReadOnlySet = bean.getIsReadOnlySet();
	if (isReadOnlySet != null && isReadOnlySet.contains(propertyId))
	    field.setReadOnly(true);

	Map<String, Validator> validatorsMap = bean.getValidatorsMap();
	if (validatorsMap != null) {
	    Validator validator = validatorsMap.get(propertyId);
	    if (validator != null) {
		field.addValidator(validator);
	    }
	}
	if (field == null)
	    throw new Error("Null field");

	return field;
    }

}

class ComboboxImpl extends ComboBox {

}
